//
// Created by alexander on 12/22/18.
//
#include <stdio.h>
#include <libavformat/avformat.h>
#include </home/alexander/CLionProjects/FFmpegLogTest/log/log.h>
#include </home/alexander/CLionProjects/FFmpegLogTest/util/util.h>
#include <stdbool.h>

int extraAudioFFmpegAPI(const char *srcFileName, const char *destFileName)
{
    setLogLevel(AV_LOG_DEBUG);
    int errorCode;
    char errors[1024];
    FILE *destFile = NULL;

    int audioStreamIndex = -1;
    int len;

    AVFormatContext *outputAvFormatContext = NULL;
    AVOutputFormat *avOutputFormat = NULL;
    AVStream *inputAVStream = NULL;
    AVStream *outputAvStream = NULL;

    AVFormatContext *inputAVFormatContext = NULL;
    AVPacket avPacket;

    av_register_all();

    errorCode = avformat_open_input(&inputAVFormatContext, srcFileName, NULL, NULL);
    if(errorCode < 0)
    {
        av_strerror(errorCode, errors, 1024);
        printf("Could not open src file：%s, %d(%s)\n", srcFileName, errorCode, errors);
        return -1;
    }

    /**retrieve audio stream*/
    errorCode = avformat_find_stream_info(inputAVFormatContext, NULL);
    if(errorCode < 0)
    {
        av_strerror(errorCode, errors, 1024);
        printf("Failed to find Stream info：%s, %d(%s)\n", srcFileName, errorCode, errors);
        return -1;
    }

    /**dump srcfile info*/
    av_dump_format(inputAVFormatContext, 0, srcFileName, 0);

    inputAVStream = inputAVFormatContext->streams[1];
    AVCodecParameters *inputAVCodecParameters = inputAVStream->codecpar;
    if(inputAVCodecParameters->codec_type != AVMEDIA_TYPE_AUDIO)
    {
        logError("The Codec type is invalid!\n", "");
        exit(1);
    }

    /**输出相关数据处理*/
    outputAvFormatContext = avformat_alloc_context();
    avOutputFormat = av_guess_format(NULL, destFileName, NULL);
    if(!avOutputFormat)
    {
        logError("Cloud not guess file format\n", "");
        exit(1);
    }

    outputAvFormatContext->oformat = avOutputFormat;

    outputAvStream = avformat_new_stream(outputAvFormatContext, NULL);
    if(!outputAvStream)
    {
        logError("Failed to create out stream!\n", "");
        exit(1);
    }
    if(inputAVFormatContext->nb_streams < 2)
    {
        logError("the number of stream is too less!\n", "");
        exit(1);
    }

    errorCode = avcodec_parameters_copy(outputAvStream->codecpar, inputAVCodecParameters);
    if(errorCode < 0)
    {
        av_strerror(errorCode, errors, 1024);
        printf("Failed to copy codec parameter, %d(%s)\n", errorCode, errors);
        exit(1);
    }
    outputAvStream->codecpar->codec_tag = 0;

    errorCode = avio_open(&outputAvFormatContext->pb, destFileName, AVIO_FLAG_WRITE);
    if(errorCode < 0)
    {
        av_strerror(errorCode, errors, 1024);
        printf("Could not open file %s, %d(%s)\n", destFileName, errorCode, errors);
        exit(1);
    }
    av_dump_format(outputAvFormatContext, 0, destFileName, 1);

    av_init_packet(&avPacket);
    avPacket.data = NULL;
    avPacket.size = 0;

    audioStreamIndex = av_find_best_stream(inputAVFormatContext, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
    if(audioStreamIndex < 0)
    {
        printf("Could not find %s stream in input file %s\n", av_get_media_type_string(AVMEDIA_TYPE_AUDIO), srcFileName);
        return AVERROR(EINVAL);
    }

    errorCode = avformat_write_header(outputAvFormatContext, NULL);
    if(errorCode < 0)
    {
        printf("Error occurred when opening output file\n");
        exit(1);
    }

    /**读取音频数据并处理   写入*/
    while (av_read_frame(inputAVFormatContext, &avPacket) >= 0)
    {
        if(avPacket.stream_index == audioStreamIndex)
        {
            avPacket.pts = av_rescale_q_rnd(avPacket.pts, inputAVStream->time_base, outputAvStream->time_base, (AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
            avPacket.dts = avPacket.pts;
            avPacket.duration = av_rescale_q(avPacket.duration, inputAVStream->time_base, outputAvStream->time_base);
            avPacket.pos = -1;
            avPacket.stream_index = 0;
            av_interleaved_write_frame(outputAvFormatContext, &avPacket);
            av_packet_unref(&avPacket);
        }
    }
    av_write_trailer(outputAvFormatContext);

    /*close input media file*/
    avformat_close_input(&inputAVFormatContext);
    if(destFile)
    {
        fclose(destFile);
    }

    avio_close(outputAvFormatContext->pb);
    return 0;
}






















